// ===================================枚举=====================================
#[test]
fn test_ipv4_enum(){
    #[derive(Debug)]
    enum IpAddrKind {
        V4,
        V6,
    }

    #[derive(Debug)]
    struct IpAddr {
        kind: IpAddrKind,
        address: String,
    }

    let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
    };
    let loopback = IpAddr{
        kind: IpAddrKind::V6,
        address: String::from("::1"),
    };

    println!("{:?} {:?}", home, loopback);
}

#[test]
fn test_enum_with_type(){
    // 带类型的枚举
    enum Ip {
        V4(String),
        V6(String),
    }

    let ipv4 = Ip::V4("127.0.0.1".to_string());
    let ipv6 = Ip::V6("::1".to_string());

    // 所有权转移
    match ipv4 {
        Ip::V4(i) => println!("this '{}' is ipv4", i),
        Ip::V6(i) => println!("this '{}' is ipv6", i),
    }

    // 所有权不转移
    match &ipv6 {
        Ip::V4(i) => println!("this '{}' is ipv4", i),
        Ip::V6(i) => println!("this '{}' is ipv6", i),
    }
}

// Option用法
#[test]
fn test_enum_option(){
    let x = Some(1);
    match &x {
        Some(v) => println!("this is a Some('{}')", v),
        None => {},
    }

    // x为None则返回默认值，enum的第一个值
    let _x1 = x.unwrap_or_default();

    // x为None则将参数当默认值返回
    let x1 = x.unwrap_or(32);

    println!("x={}", x1);

    // 使用if let来匹配关心的值, 以简化控制流match代码
    if let Some(1) = x {
        println!("yes, this is 1.")
    }

    // x为None则panic,这儿放最后面不然expect后面的代码执行不到
    x.expect("x panic!");
}

#[test]
fn test_error(){
    if let Ok(num) = "123".to_string().parse::<i32>(){
        println!("{}", num);
    }

}
